import { HttpClientOptions } from "../../domain/httpClientOptions";
import { InternalRequestConfig } from "../../domain/httpRequestConfig";
import { obtainEvent } from "../../event/httpEventHelper";
import { aesEncryptHeader } from "../../util/encrypt";
import { buildUUID } from "../../util/uuid";
import { Filter } from "../filter";

export const tokenFilter: Filter = {
  order(): number {
    return 0;
  },
  request(
    config: InternalRequestConfig<any>,
    options: HttpClientOptions
  ): Promise<InternalRequestConfig<any>> {
    // 处理token配置
    return handlerToken(config, options);
  },
};

const handlerToken = async (
  config: InternalRequestConfig,
  options: HttpClientOptions
): Promise<InternalRequestConfig<any>> => {
  if (!options.requestToken) {
    return config;
  }
  const {
    enable = false,
    authenticationScheme,
    aesKey,
    split,
  } = options.requestToken!;
  if (!enable) {
    return config;
  }
  // 为每个请求添加nonce请求头
  config.headers = Object.assign({}, config.headers, { nonce: buildUUID() });
  const event = obtainEvent(options);
  // 请求之前处理config
  let token = null;
  try {
    // @ts-ignore
    token = event.authorizationTokenInfuse();
  } catch (error) {
    console.warn("调用token注入失败,请检查是否实现该方法", error);
  }
  if (!token) {
    console.error(
      "[HttpClient]: 请求开启了token认证，但是没有在事件中获取到token，请检查相关代码"
    );
    return config;
  }
  let authorization = aesEncryptHeader(
    token,
    config.headers.nonce,
    aesKey,
    split
  );
  if (authenticationScheme) {
    authorization = authenticationScheme + authorization;
  }
  (config as Record<string, any>).headers.Authorization = authorization;
  return config;
};
